
const QG = 'qg'
//平台名称
const PlatName = {
    DEV: 'dev',
    WX: 'wx',
    QQ: 'qq',
    TT: 'tt',
    KS: 'ks',
    VIVO: 'vivo',
    OPPO: 'oppo',
    SWAN: 'swan',//百度
    F399: 'h5api',
    COCOS: 'AdSDK',
    NATIVE: 'SDKNative',
}
const SDK_NAMES = [PlatName.KS, PlatName.QQ, PlatName.TT, PlatName.WX, QG, PlatName.SWAN, PlatName.F399, PlatName.COCOS]
function isNative() {
    return window['PlatformClass'] != undefined || window['native'] != undefined || window['jsb'] != undefined
}

function getChannelName(name) {
    for (let index = 0; index < SDK_NAMES.length; index++) {
        let platfom = SDK_NAMES[index]
        let pname = platfom
        const sdk = window[platfom]
        if (sdk) {
            // console.log(' sdk not null ')
            if (platfom == QG) {
                let sys = sdk.getSystemInfoSync()
                console.log(' sys ------------', sys.brand)
                pname = sys.brand.toLowerCase()
            }
            return pname;
        }
    }
    if (name != PlatName.DEV) {
        return name;
    } else {
        if (isNative()) {
            return PlatName.NATIVE
        } else {
            return PlatName.DEV
        }
    }
}
window['getChannelName'] = getChannelName;
function getPlatName() {
    for (let index = 0; index < SDK_NAMES.length; index++) {
        let platfom = SDK_NAMES[index]
        // let pname = platfom
        const sdk = window[platfom]
        if (sdk) {
            return platfom;
        }
    }
    if (isNative()) {
        return PlatName.NATIVE
    } else {
        return PlatName.DEV
    }
}
window['getPlatName'] = getPlatName;



const CLASS_NAME = 'sdk/JSBridge'

const SHOW_BANNER = 'showBanner'
const HIDE_BANNER = 'hideBanner'
const LOAD_BANNER = 'loadBanner'

const SHOW_INSERT = 'showInsertAd'
const LOAD_INSERT = 'loadInsertAd'

const LOAD_REWARD = 'loadRewardAd'
const SHOW_REWARD = 'showRewardAd'

var JsNativeBridge = {
    callbacks: {},
    isCocos() {
        return window['cc'] != undefined && (window['jsb'] != undefined || window['native'] != undefined)
    },
    isLaya() {
        return window['conchConfig'] != undefined && window['PlatformClass'] != undefined
    },
    callStaticMethod(className, methodName, parameters, methodSignOrFunc) {
        if (JsNativeBridge.isCocos()) {
            JsNativeBridge.cocosCallStaticMethod(className, methodName, parameters, methodSignOrFunc)
        } else {
            JsNativeBridge.layaCallStaticMethod(className, methodName, parameters, methodSignOrFunc)
        }
    },
    layaCallStaticMethod(className, methodName, parameters, param) {
        var os = window['conchConfig'].getOS();
        var callback = param.callback;
        var bridge;
        let PlatformClass = window['PlatformClass']
        if (os == "Conch-ios") {
            bridge = PlatformClass.createClass(className);//创建脚步代理
            if (!bridge) {
                console.log(' callStatic Method class name ', className, methodName, parameters)
                return;
            }
            if (callback) {
                bridge.callWithBack(function (value) {
                    var obj = JSON.parse(value)
                    console.log(obj);
                    callback(obj)
                }, methodName + ":", JSON.stringify(parameters));

            } else {
                bridge.call(methodName, parameters)

            }

        }
        else if (os == "Conch-android") {
            //需要完整的类路径，注意与iOS的不同
            bridge = PlatformClass.createClass(className);//创建脚步代理
            if (!bridge) {
                console.log(' callStatic Method class name ', className, methodName, parameters)
                return;
            }
            if (callback) {
                bridge.callWithBack(function (value) {
                    var obj = JSON.parse(value)
                    console.log(obj);
                    callback(obj)
                }, methodName, JSON.stringify(parameters));
            } else {
                bridge.call(methodName, parameters)
            }

        }
    },
    cocosCallStaticMethod(className, methodName, parameters, param) {
        let methodSignature = param.methodSignature;
        if (!methodSignature) {
            methodSignature = "(Ljava/lang/String;)V";
        }
        let callback = param.callback;
        if (callback) {
            let c = JsNativeBridge.callbacks[className]
            if (!c) {
                c = {}
                JsNativeBridge.callbacks[className] = c;
            }
            c[methodName] = callback;
        }
        let cc = window['cc']
        let jsb = window['jsb'] || window['native']
        console.log(" JsNativeBridge callStaticMethod ", cc.sys.isNative)
        if (!cc.sys.isNative) {
            return -1;
        }
        console.log(" JsNativeBridge callStaticMethod ", methodName, parameters)
        if (cc.sys.os == cc.sys.OS_IOS) {
            let result = jsb['reflection'].callStaticMethod(className, methodName, parameters);
            if (result) {
                console.log("callStaticMethod ios  ", result);
            }
        } else {
            console.log(" JsNativeBridge callStaticMethod adroid ")
            let result = jsb['reflection'].callStaticMethod(className, methodName, methodSignature, parameters)
            console.log("callStaticMethod result  ", result);
            if (result) {

                return result;
            }
        }
    },

    javaCallback(data) {
        if (data) {
            data = JSON.parse(data)
            if (data) {
                let className = data.className;
                let methodName = data.methodName;
                let c = JsNativeBridge.callbacks[className]
                if (c) {
                    let callback = c[methodName]
                    if (callback) {
                        callback(data.result)
                        c[methodName] = null;
                    }
                }
            }

        }
    },
    bannerResize(data) {

    },
    rewardAdClose(data) {

    }
}
class SdkEvent {
    constructor() {
        this.loadListener = []
    }
    on(func) {
        let index = this.loadListener.indexOf(func)
        if (index < 0) {
            this.loadListener.push(func)
        }
    }
    off(func) {
        let index = this.loadListener.indexOf(func)
        if (index >= 0) {
            this.loadListener.splice(index, 1)
        }
    }
    emit(data) {
        for (let index = 0; index < this.loadListener.length; index++) {
            const element = this.loadListener[index]
            element(data)
        }
    }
    clear() {
        this.loadListener.length = 0;
    }
}

class NativeAd {
    constructor(data) {
        this.data = data
        this.loadListener = new SdkEvent()
        this.errorListener = new SdkEvent()
    }
    onLoad(func) {
        this.loadListener.on(func)
    }
    offLoad(func) {
        this.loadListener.off(func)
    }
    emitLoad(data) {
        this.loadListener.emit(data)
    }
    onError(func) {
        this.errorListener.on(func)

    }
    offError(func) {
        this.errorListener.off(func)
    }
    emitError(data) {
        this.errorListener.emit(data)
    }
    destroy() {
        this.loadListener.clear();
        this.errorListener.clear();
    }
}







//原生插屏广告
class NativeInterstitialAd extends NativeAd {
    constructor(data) {
        super(data)
    }
    show() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, SHOW_INSERT, '')
    }
    load() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, LOAD_INSERT, JSON.stringify(this.data), { callback: this.loadCallback.bind(this) })
    }
    loadCallback(result) {
        if (result == 1) {
            this.insertIns.emitLoad(null)
        } else {
            this.insertIns.emitError('加载失败')
        }

    }
}



class NativeRewardedVideoAd extends NativeAd {
    constructor(data) {
        super(data)
        this.closeListener = new SdkEvent()
    }
    load() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, LOAD_REWARD, JSON.stringify(this.data), { callback: this.loadCallback.bind(this) })
    }
    show() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, SHOW_REWARD, '')
    }
    loadCallback(result) {
        if (result == 1) {
            this.emitLoad(null)
        } else {
            this.emitError('加载失败')
        }
    }
    rewardAdClose(result) {
        this.emitClose({ isEnded: result })
    }
    destroy() {
        super.destroy();
        this.closeListener = new SdkEvent()
    }
    onClose(func) {
        this.closeListener.on(func)
    }
    offClose(func) {
        this.closeListener.off(func)
    }
    emitClose(data) {
        this.closeListener.emit(data)
    }
}
// NativeRewardedVideoAd.prototype = new NativeAd();






class NativeBannerAd extends NativeAd {
    constructor(data) {
        super(data)
        this.resizeListener = new SdkEvent()
    }
    load() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, LOAD_BANNER,
            JSON.stringify(this.data), { callback: this.loadCallback.bind(this) })
    }
    hide() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, HIDE_BANNER, '')
    }
    show() {
        JsNativeBridge.callStaticMethod(CLASS_NAME, SHOW_BANNER, '')
    }
    destroy() {
        super.destroy();
        this.resizeListener = new SdkEvent()
    }
    //java call functions 
    loadCallback(result) {
        console.log('bannerAdCallback result ', result)
        if (result == 1) {
            this.emitLoad(null)
        } else {
            this.emitError('加载失败')
        }
    }
    bannerResize(size) {
        this.emitLoad(size)
    }
    onResize(func) {
        this.resizeListener.on(func)
    }
    offResize(func) {
        this.resizeListener.off(func)
    }
    emitResize(data) {
        this.resizeListener.emit(data)
    }
}

//原生适配
class Native {
    constructor() {
    }
    createBannerAd(data) {
        if (!this.bannerIns) {
            this.bannerIns = new NativeBannerAd(data)
        }
        return this.bannerIns
    }
    createRewardedVideoAd(data) {
        if (!this.rewardIns) {

            this.rewardIns = new NativeRewardedVideoAd(data)
        }
        return this.rewardIns
    }
    createInterstitialAd(data) {
        if (!this.insertIns) {
            this.insertIns = new NativeInterstitialAd(data)
        }
        return this.insertIns
    }
    getSystemInfoSync() {
    }
    getDataPath() {
        return ''
    }
}



class AdAdapter {
    constructor(ad) {
        this._ad = ad
        this.loadListener = new SdkEvent()
        this.errorListener = new SdkEvent()
        this.closeListener = new SdkEvent()
    }
    onLoad(func) {
        this.loadListener.on(func)
    }
    offLoad(func) {
        this.loadListener.off(func)
    }
    onError(func) {
        this.errorListener.on(func)
    }
    offError(func) {
        this.errorListener.off(func)
    }
    onClose(func) {
        this.closeListener.on(func)
    }
    offClose(func) {
        this.closeListener.off(func)
    }
    load(func) {
    }
}





class F399RewardAd extends AdAdapter {
    constructor(_ad) {
        super(_ad)
        if (this._ad) {
            this._ad.canPlayAd((data) => {
                this.remain = data.remain
                this.canPlayAd = data.canPlayAd
                console.log("loadConfig 是否可播放广告", this.canPlayAd, "剩余次数", this.remain)
            })
        }

    }
    show() {
        this._ad.playAd((obj) => {
            console.log('代码:' + obj.code + ',消息:' + obj.message)
            if (obj.code === 10000) {
                console.log('开始播放')
            } else if (obj.code === 10001) {
                console.log('播放结束')
                this.closeListener.emit({ isEnded: true })
            } else {
                console.log('广告异常')
                this.errorListener.emit({ msg: obj.message })
            }
        })
    }
    load() {
        this.loadListener.emit()
    }
}



//开发环境
class Dev {
    constructor() {
    }
    request(param) {
        let url = param.url
        let data = param.data
        let method = param.method ? param.method : "GET"
        let isOk = false
        console.log('sendHttpRequest  address ', url)
        let xhr = new XMLHttpRequest()
        xhr.timeout = param.timeout
        xhr.ontimeout = function () {
            param.fail('ontimeout')
        }
        xhr.onload = function () {
            console.log('onload xhr.status', xhr.status, 'xhr.readyState ', xhr.readyState)
            if (xhr.status >= 200 && xhr.status < 400) {
                if (isOk) {
                    return
                }
                isOk = true
                var data = xhr.responseText
                let temp = { data: data }
                param.success(temp)
            } else {
                param.fail('onload error')
            }
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    if (isOk) {
                        return
                    }
                    isOk = true
                    var data = xhr.responseText
                    let temp = { data: data }
                    param.success(temp)
                } else {
                    param.fail('onload error')
                }
            }
        }
        xhr.open(method, url, true)
        let innerHeaer = param.header
        if (innerHeaer) {
            for (var key in innerHeaer) {
                if (innerHeaer[key]) {
                    xhr.setRequestHeader(key, innerHeaer[key])
                }
            }
        }
        try {
            xhr.send(data)
        } catch (error) {
            param.fail('send error ' + error)
        }
    }
}

class SDKAdatper {
    constructor() {
        this._sdk = null
    }
    init() {
    }
    setSDK(d) {
        this._sdk = d
    }
    getSDK() {
        return this._sdk
    }
    dev() {

    }
    SDKNative() {

    }
    wx() {
        let shareAppMessage = this._sdk.shareAppMessage
        if (this._sdk.onShow) {
            this._sdk.onShow(() => {
                this.backGame()
            })
        }
        this._sdk.shareAppMessage = function (obj) {
            if (shareAppMessage) {
                this._param = obj
                shareAppMessage(obj)
                this.time = Date.now()
            }
        }
    }
    backGame() {
        if (this._param) {
            let disTime = Date.now() - this.time
            if (disTime >= 3000) {
                if (this._param.success) {
                    this._param.success()
                }
            } else {
                if (this._param.fail) {
                    this._param.fail()
                }
            }
            this._param = null
        }
    }
    qg() {
        let sys = this._sdk.getSystemInfoSync()
        console.log(' sys ------------', sys.brand)
        let pname = sys.brand.toLowerCase()
        switch (pname) {
            case 'vivo':
                this._sdk.getDataPath = function () {
                    return 'internal://files/'
                }
                this._sdk.showImage = function (_tempFilePath) {
                    this._sdk.previewImage(_tempFilePath)
                }
                break;
            case 'oppo':
                this._sdk.showImage = function (_tempFilePath) {
                    this._sdk.previewImage(_tempFilePath)
                }
                break;
        }


    }
    tt() {
    }
    qq() {
    }
    h5api() {
        this._sdk.createRewardedVideoAd = function (obj) {
            return new F399RewardAd(this._sdk)
        }
    }
    // cocos sdk 
    AdSDK() {

        let createBannerAd = this._sdk.createBannerAd
        this._sdk.createBannerAd = function (obj) {
            return createBannerAd(obj.key, obj.adUnitId, obj.num)
        }

        let createInterstitialAd = this._sdk.createInterstitialAd
        this._sdk.createInterstitialAd = function (obj) {
            return createInterstitialAd(obj.key, obj.adUnitId, obj.num)
        }

        let createRewardedVideoAd = this._sdk.createRewardedVideoAd
        this._sdk.createRewardedVideoAd = function (obj) {
            return createRewardedVideoAd(obj.key, obj.adUnitId, obj.num)
        }

        this._sdk.getDataPath = function () {
            let rt = window['runtime']()
            return rt.env.USER_DATA_PATH + '/'
        }

        this._sdk.getFileSystemManager = function () {
            if (window['runtime']) {
                let rt = window['runtime']()
                if (rt) {
                    return rt.gtFileSystemManager()
                }
            }
            return null
        }
    }
    ks() {

        this._sdk.getGameRecorderManager = function () {
            return this._sdk.getGameRecorder()
        }
        let recorder = this._sdk.getGameRecorderManager()

        recorder.publish = function (param) {
            recorder.publishVideo(param)
        }
        recorder.onStart = function (func) {
            recorder.on('start', func)
        }
        recorder.onStop = function (func) {
            recorder.on('stop', func)
        }
        recorder.onResume = function (func) {
            recorder.on('resume', func)
        }
        recorder.onPause = function (func) {
            recorder.on('pause', func)
        }
        recorder.onError = function (func) {
            recorder.on('error', func)
        }
    }
}

let adapter = new SDKAdatper()
let platName = getPlatName();
console.log(' platName ', platName)
if (platName == PlatName.NATIVE) {
    window['JsNativeBridge'] = JsNativeBridge
    window[PlatName.NATIVE] = new Native()
} else if (platName == PlatName.DEV) {
    window[PlatName.DEV] = new Dev()
}

if (platName) {
    const s = window[platName]
    if (s) {
        adapter.setSDK(s)
        if (adapter[platName]) {
            adapter[platName]()
        } else {
            console.warn(' parse pname is null ', platName)
        }
    }
}


let platform = adapter.getSDK();
window['platform'] = platform

